package cn.diancan.service.impl;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Random;

import javax.annotation.Resource;

import cn.diancan.dto.PurchaseSaleOrderDto;
import cn.diancan.dto.PurchaseSaleOrderByTypeDto;
import cn.diancan.model.*;
import cn.diancan.model.types.*;
import cn.diancan.service.*;
import cn.diancan.util.DoubleArith;
import cn.diancan.vo.PurchaseSaleOrderCountVo;
import cn.diancan.vo.SaleOrderCarVo;
import cn.diancan.vo.SaleProductCarVo;
import cn.diancan.vo.model.PurchaseSaleOrderVo;
import org.apache.commons.beanutils.BeanUtils;
import org.springframework.stereotype.Component;

import cn.diancan.dao.MyBaseDao;
import cn.diancan.dto.PurchaseSaleOrderProductDto;
import cn.diancan.dto.PurchaseSaleOrderStatisticsDto;
import cn.diancan.dto.query.PurchaseSaleOrderProductQuery;
import cn.diancan.exception.OutMsgException;
import cn.diancan.util.DateUtil;
import cn.diancan.util.MoneyUtil;
import cn.diancan.util.ObjectUtils;
import cn.diancan.vo.model.PurchaseSaleOrderProductVo;
import cn.diancan.vo.other.Pager;
import cn.diancan.vo.other.ResultVoUtil;

@Component("purchaseSaleOrderService")
public class PurchaseSaleOrderServiceImpl implements PurchaseSaleOrderService {

    @Resource(name = "MyBaseDao")
    private MyBaseDao<PurchaseSaleOrder> purchaseOrderDao;

    @Resource(name = "MyBaseDao")
    private MyBaseDao<PurchaseSaleOrderProduct> purchaseOrderProductDao;

    @Resource(name = "productService")
    private ProductService productService;

    @Resource(name = "goodsService")
    private GoodsService goodsService;

    @Resource(name = "shopClerkService")
    private ShopClerkService shopClerkService;


    @Override
    public PurchaseSaleOrder saveCreatePurchaseOrder(List<PurchaseSaleOrderProductVo> productVoList, String outOrderNumber, String orderMark, String ip) throws OutMsgException, Exception {
        if (null == productVoList || productVoList.size() <= 0) {
            throw new OutMsgException("请提交商品内容");
        }
        for (int i = 0; i < productVoList.size(); i++) {
            PurchaseSaleOrderProductVo vo = productVoList.get(i);
            vo.setDiscount(1f);
        }
        //return  savePurchaseSaleOrder(productVoList,  PurchaseSaleOrderType.PURCHASE,  outOrderNumber,null,orderMark);
        return savePurchaseSaleOrder(productVoList, PurchaseSaleOrderType.PURCHASE, outOrderNumber, null, null, orderMark, 2, null, null, 1, 1, ip);
    }

    @Override
    public PurchaseSaleOrder saveCreateSaleOrder(List<PurchaseSaleOrderProductVo> productVoList, String outOrderNumber, Integer outRealTotalQuantity, Double outRealTotalPrice, String orderMark, Integer moneyFloatDigit, String clientCreateTime, Long shopClerkId, Integer payType, String ip) throws OutMsgException, Exception {

        //return  savePurchaseSaleOrder(productVoList,  PurchaseSaleOrderType.SALE,  outOrderNumber,outRealTotalPrice,orderMark);
        return savePurchaseSaleOrder(productVoList, PurchaseSaleOrderType.SALE, outOrderNumber, outRealTotalQuantity, outRealTotalPrice, orderMark, moneyFloatDigit, clientCreateTime, shopClerkId, 1, payType, ip);
    }

    public PurchaseSaleOrder findByOutOrderNumber(String outOrderNumber) throws OutMsgException {
        if (null != outOrderNumber && "".equals(outOrderNumber.trim())) {
            throw new OutMsgException("参数错误");
        }
        outOrderNumber = outOrderNumber.trim();
        return purchaseOrderDao.get("FROM PurchaseSaleOrder WHERE outOrderNumber=? ", new Object[]{outOrderNumber});
    }

    /**
     * String outOrderNumber; //外部进货单
     * <p>
     * Integer outRealTotalQuantity;//提交上来的（参考）
     * Double outRealTotalPrice; //提交上来的（参考）
     * <p>
     * String orderMark; //订单说明
     * <p>
     * Integer moneyFloatDigit;  //小数点后几位
     * String clientCreateTime; //
     *
     * @param productVoList
     * @param orderType
     * @param outOrderNumber
     * @param outRealTotalQuantity
     * @param outRealTotalPrice
     * @param orderMark
     * @param moneyFloatDigit
     * @param clientCreateTime
     * @return
     * @throws OutMsgException
     * @throws Exception
     */
    private PurchaseSaleOrder savePurchaseSaleOrder(List<PurchaseSaleOrderProductVo> productVoList, PurchaseSaleOrderType orderType, String outOrderNumber, Integer outRealTotalQuantity, Double outRealTotalPrice, String orderMark, Integer moneyFloatDigit, String clientCreateTime, Long shopClerkId, Integer isPay, Integer payType, String ip) throws OutMsgException, Exception {


        Date date = new Date();
        String orderNumber = findOrderNumber();//getOrderNumber(orderType.getPrefix(), date);

        PurchaseSaleOrder purchaseOrder = new PurchaseSaleOrder();
        purchaseOrder.setOrderNumber(orderNumber);

        purchaseOrder.setCreateTime(DateUtil.currentDateTime(date));
        purchaseOrder.setIsDelete(CommonType.Delete.NO);
        purchaseOrder.setPurchaseSaleOrderType(orderType.getType());

        if (null != findByOutOrderNumber(outOrderNumber)) {
            throw new OutMsgException("重复单号");
        }
        purchaseOrder.setIp(ip);
        //外部提交的数据
        purchaseOrder.setOutOrderNumber(outOrderNumber);
        purchaseOrder.setClientCreateTime(clientCreateTime);
        purchaseOrder.setMoneyFloatDigit(moneyFloatDigit);
        purchaseOrder.setOutRealTotalQuantity(outRealTotalQuantity);
        purchaseOrder.setOutRealTotalPrice(outRealTotalPrice);
        purchaseOrder.setOrderMark(orderMark);
        purchaseOrder.setIsPay(1);
        purchaseOrder.setShopClerkId(shopClerkId);
        purchaseOrder.setPayType(payType);

        purchaseOrderDao.save(purchaseOrder);

        Long purchaseOrderId = purchaseOrder.getId();



        Double orderTotalPrice = 0d;
        Integer orderTotalQuantity = 0;
        Double orderRealTotalPrice = 0d; //实际(实际总价)

        for (int i = 0; i < productVoList.size(); i++) {
            PurchaseSaleOrderProductVo productVo = productVoList.get(i);
            Product product = productService.findByProductId(productVo.getProductId());
            if (null == product) {
                throw new OutMsgException("该规格货品不存在");
            }

            Long goodsId = product.getGoodsId();
            Goods goods = goodsService.findByGoodsId(goodsId);
            if (null == goods) {
                throw new OutMsgException("该货品不存在");
            }

            Double retailPrice = goods.getRetailPrice();
            Double tagPrice = goods.getTagPrice();

            Integer quantity = productVo.getQuantity();
            Float discount = productVo.getDiscount(); //折扣
            Double discountPrice = productVo.getDiscountPrice(); //折扣价
            Double realRetailPrice = productVo.getRealRetailPrice();//结算价
            Double realTotalPrice = productVo.getRealTotalPrice(); //实际总价
            Integer productSaleStatus = productVo.getProductSaleStatus();

            PurchaseSaleOrderProductStatusType purchaseSaleOrderProductStatusType = null;

            if (PurchaseSaleOrderType.PURCHASE.equals(orderType)) {
                discount = 1f;
                discountPrice = retailPrice;
                realRetailPrice = MoneyUtil.mul(retailPrice, quantity);
                realTotalPrice = MoneyUtil.mul(retailPrice, quantity);
                purchaseSaleOrderProductStatusType = PurchaseSaleOrderProductStatusType.PURCHASE;
                productSaleStatus = purchaseSaleOrderProductStatusType.getType();
            } else {
                purchaseSaleOrderProductStatusType = PurchaseSaleOrderProductStatusType.find(productSaleStatus);
            }

            if (null == purchaseSaleOrderProductStatusType) {
                throw new OutMsgException("参数错误");
            }


            PurchaseSaleOrderProduct purchaseOrderProduct = new PurchaseSaleOrderProduct();

            purchaseOrderProduct.setShopClerkId(shopClerkId);
            purchaseOrderProduct.setGoodsId(goodsId);
            purchaseOrderProduct.setIsDelete(CommonType.Delete.NO);
            purchaseOrderProduct.setProductId(product.getId());
            purchaseOrderProduct.setPurchaseOrderId(purchaseOrderId);

            purchaseOrderProduct.setRetailPrice(retailPrice);
            purchaseOrderProduct.setTagPrice(tagPrice);

            //new
            purchaseOrderProduct.setDiscount(discount);
            purchaseOrderProduct.setDiscountPrice(discountPrice);
            purchaseOrderProduct.setProductSaleStatus(productSaleStatus);


            //使用负数
            if (purchaseSaleOrderProductStatusType.isOperating()) {
                if (purchaseSaleOrderProductStatusType.getUseType().equals(TranUseType.SUBNONEY)) {
                    realRetailPrice = MoneyUtil.sub(0, realRetailPrice);
                    realTotalPrice = MoneyUtil.sub(0, realTotalPrice);
                    quantity = 0 - quantity;
                }
            }
            purchaseOrderProduct.setQuantity(quantity);
            purchaseOrderProduct.setRealRetailPrice(realRetailPrice);
            purchaseOrderProduct.setRealTotalPrice(realTotalPrice);


            //计算出来的总价
            Double totalPrice = 0d;
            if (purchaseSaleOrderProductStatusType.isOperating()) {
                totalPrice = MoneyUtil.mul(retailPrice, quantity);
            }


            purchaseOrderProduct.setTotalPrice(totalPrice);
            purchaseOrderProductDao.save(purchaseOrderProduct);

            //add to total
            orderTotalQuantity = purchaseOrderProduct.getQuantity() + orderTotalQuantity;

            if (purchaseSaleOrderProductStatusType.isOperating()) {
                orderTotalPrice = MoneyUtil.add(orderTotalPrice, purchaseOrderProduct.getTotalPrice());
                orderRealTotalPrice = MoneyUtil.add(orderRealTotalPrice, purchaseOrderProduct.getRealTotalPrice());

		/*if(purchaseSaleOrderProductStatusType.getUseType().equals(TranUseType.ADDMONEY)){
		    orderTotalPrice = MoneyUtil.add(orderTotalPrice,purchaseOrderProduct.getTotalPrice() ); 
		    orderRealTotalPrice = MoneyUtil.add(orderRealTotalPrice ,purchaseOrderProduct.getRealTotalPrice() );
		}else{
		    orderTotalPrice = MoneyUtil.sub(orderTotalPrice,purchaseOrderProduct.getTotalPrice() ); 
		    orderRealTotalPrice = MoneyUtil.sub(orderRealTotalPrice ,purchaseOrderProduct.getRealTotalPrice() );
		}*/
            }



        }

        purchaseOrder.setTotalPrice(orderTotalPrice);
        purchaseOrder.setTotalQuantity(orderTotalQuantity);
        purchaseOrder.setRealTotalPrice(orderRealTotalPrice);


        purchaseOrder.setOrderStatus(0);
        purchaseOrderDao.update(purchaseOrder);

        return purchaseOrder;
    }
    
   /* public static void main(String[] args) {
	Map<Long ,String> m = new LinkedHashMap<Long ,String>();
	 m.put(12l, "12312");
	 m.put(11l, "12312");
	 m.put(14l, "12312");
	 m.put(17l, "12312");
	 m.put(60l, "12312");
	 m.put(11l, "1231222");//顺序不会变,值会变 
	 
	for (Entry<Long ,String> entry :m.entrySet()) {
	  System.out.println(entry.getKey()+entry.getValue());
	}
	
    }*/

    /**
     * 生成订单
     *
     * @param date
     * @return
     */
    private String getOrderNumber(String qz, Date date) {
        // 30=zw
        Date d = new Date();
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(d);

        int hours = calendar.get(Calendar.HOUR_OF_DAY); // 时
        int minutes = calendar.get(Calendar.MINUTE);    // 分
        int seconds = calendar.get(Calendar.SECOND);    // 秒
        //return "30" + (new SimpleDateFormat("yyyyMMdd")).format(date)+ date.getTime() + userId + (new Random().nextInt(8999) + 1000);
        int tm = hours * 60 * 60 + minutes * 60 + seconds;
        return qz + (new SimpleDateFormat("yyyyMMdd")).format(date) + tm + (new Random().nextInt(8999) + 1000);
    }

    @Resource(name = "MyBaseDao")
    private MyBaseDao<PurchaseSaleOrderNumber> purchaseSaleOrderNumberDao;


    public String findOrderNumber(){
        Date now = new Date();
        String date= DateUtil.currentDate(now);
        PurchaseSaleOrderNumber purchaseSaleOrderNumber = purchaseSaleOrderNumberDao.get("FROM PurchaseSaleOrderNumber WHERE createDate=?",new Object[]{date});
        if(null==  purchaseSaleOrderNumber ){
            purchaseSaleOrderNumber = new PurchaseSaleOrderNumber();
            purchaseSaleOrderNumber.setCreateDate(date);
            purchaseSaleOrderNumber.setDateTime(DateUtil.currentDateTime());
            String dateStr = DateUtil.currentDate2(now);
            purchaseSaleOrderNumber.setStartNumber(Long.valueOf( dateStr+"0001" ));
            purchaseSaleOrderNumber.setCount(1);
            purchaseSaleOrderNumberDao.save(purchaseSaleOrderNumber);
        }
        purchaseSaleOrderNumber.setStartNumber(purchaseSaleOrderNumber.getStartNumber()+1);
        purchaseSaleOrderNumber.setCount(purchaseSaleOrderNumber.getCount()+1);
        purchaseSaleOrderNumber.setDateTime(DateUtil.currentDateTime());
        purchaseSaleOrderNumberDao.update(purchaseSaleOrderNumber);
        return purchaseSaleOrderNumber.getStartNumber().toString();
    }


    @Override
    public PurchaseSaleOrderProduct findPurchaseOrderProduct(Long purchaseOrderId, Long goodsId, Long productId) throws OutMsgException {
        if (null == purchaseOrderId) {
            throw new OutMsgException("参数错误");
        }
        if (null == goodsId) {
            throw new OutMsgException("参数错误");
        }
        if (null == productId) {
            throw new OutMsgException("参数错误");
        }

        return purchaseOrderProductDao.get("FROM PurchaseOrderProduct WHERE purchaseOrderId=? AND goodsId=? AND productId=? AND isDelete=?",
                new Object[]{purchaseOrderId, goodsId, productId, CommonType.Delete.NO});
    }





    /**
     * private Long brandId; //Brand 外键
     * <p>
     * private Long firstGoodsCategoryId;
     * private Long secondGoodsCategoryId;
     * <p>
     * private Long goodsCategoryId; //产品分类
     * private String goodsCategoryPath;
     * <p>
     * <p>
     * private String goodsNumber; //唯一  ==Goods_No
     * private String goodsName;//Goods_Name
     * private String goodsDescription;
     * private String createTime;
     * <p>
     * private String goodsBarCode; //条码 --前面一段
     * <p>
     * <p>
     * //货品的价格.
     * private String rangeStr;
     * private Double tagPrice;    //吊牌价
     * private Double retailPrice;  //销售价格
     * private String unit;
     * <p>
     * <p>
     * private String year; //年份
     * private String season; //季节
     * private Integer applySex; // 0 女  1 男   2 全部
     * private Double wholeSalePrice;//
     * private String goodsRemark;
     * <p>
     * private Integer totalStockCount; //总库存
     */

    @Override
    public Pager findPagerBySaleOrderProduct(Pager pager, PurchaseSaleOrderProductQuery query, PurchaseSaleOrderStatisticsDto statisticsDto) throws OutMsgException, Exception {

        List<Object> param = new ArrayList<Object>();
        Integer pageNo = pager.getPageNumber();
        Integer row = pager.getPageSize();


        String sql = "Select p1.purchaseOrderId,p1.goodsId,p1.productId,p1.tagPrice AS orderTagPrice,p1.retailPrice AS orderRetailPrice,p1.quantity,p1.totalPrice,p1.discount,p1.discountPrice,p1.realRetailPrice,p1.realTotalPrice,p1.productSaleStatus";

        sql += ",p2.orderNumber,p2.outOrderNumber,p2.totalPrice AS orderTotalPrice,p2.totalQuantity,p2.realTotalPrice AS orderRealTotalPrice,p2.outRealTotalQuantity,p2.outRealTotalPrice,p2.orderStatus,p2.orderMark,p2.purchaseSaleOrderType,p2.moneyFloatDigit";
        sql += ",p2.clientCreateTime,p2.shopClerkId,p2.payType,p2.isPay,p2.ip";

        sql += ",p4.barCode,p4.stockCount";
        sql += ",g5.goodsNumber,g5.goodsName,p1.goodsName AS goodsName2,g5.goodsImage,g5.tagPrice,g5.retailPrice,g5.unit";
        sql += ",first_gc.categoryName AS firstGoodsCategoryName,second_gc.categoryName AS secondGoodsCategoryName";

        if (query.getIsStatistics().equals(CommonType.Statistics.YES)) {
            sql += ",sum(p1.quantity) AS totalQuantityCount,sum(p1.realTotalPrice) AS realTotalPriceCount ";
        }
        String hql = " FROM PurchaseSaleOrderProduct AS p1 " +
                "LEFT JOIN PurchaseSaleOrder AS p2 ON p1.purchaseOrderId=p2.id " +
                "LEFT JOIN Product AS p4 ON p1.productId=p4.id " +
                "LEFT JOIN Goods AS g5 ON p1.goodsId=g5.id " +
                "LEFT JOIN GoodsCategory AS first_gc ON g5.firstGoodsCategoryId=first_gc.id " +
                "LEFT JOIN GoodsCategory AS second_gc ON g5.secondGoodsCategoryId=second_gc.id " +
                //"LEFT JOIN "+
                "WHERE p1.isDelete=? ";
        param.add(CommonType.Delete.NO);

        if (ObjectUtils.isNotBlank(query.getShopClerkId())) {
            hql += " AND p2.shopClerkId=? ";
            param.add(query.getShopClerkId());
        }
        if (ObjectUtils.isNotBlank(query.getFirstGoodsCategoryId())) {
            hql += " AND g5.firstGoodsCategoryId=? ";
            param.add(query.getFirstGoodsCategoryId());
        }
        if (ObjectUtils.isNotBlank(query.getSecondGoodsCategoryId())) {
            hql += " AND g5.secondGoodsCategoryId=? ";
            param.add(query.getSecondGoodsCategoryId());
        }
        if (ObjectUtils.isNotBlank(query.getStartTime())) {
            hql += " AND p2.clientCreateTime>=? ";
            param.add(query.getStartTime());
        }
        if (ObjectUtils.isNotBlank(query.getEndTime())) {
            hql += " AND p2.clientCreateTime<=? ";
            param.add(query.getEndTime());
        }
        if (PurchaseSaleOrderProductStatusType.checkExists(query.getProductSaleStatus())) {
            hql += " AND p1.productSaleStatus=? ";
            param.add(query.getProductSaleStatus());
        }
        if (ObjectUtils.isNotBlank(query.getBarCode())) {
            hql += " AND p4.barCode=? ";
            param.add(query.getBarCode());
        }
        if (ObjectUtils.isNotBlank(query.getGoodsNumber())) {
            hql += " AND g5.goodsNumber=? ";
            param.add(query.getGoodsNumber());
        }
        if (ObjectUtils.isNotBlank(query.getOutOrderNumber())) {
            hql += " AND p2.outOrderNumber=? ";
            param.add(query.getOutOrderNumber());
        }


        /**
         *     private Integer isStatistics; //1 YES  0 NO
         private Integer statisticsType;//1.ProductId 2.GoodsId
         private Integer byOrderType;//1.clientCreateTime 2.totalQuantityCount 3.realTotalPriceCount
         private Integer byOrderSortType;//1.ASC 2.DESC
         */
        String orderSql = "";
        if (query.getIsStatistics().equals(CommonType.Statistics.YES)) {
            if (query.getStatisticsType().equals(1)) {
                hql += " Group By p1.productId ";
            } else if (query.getStatisticsType().equals(2)) {
                hql += " Group By p1.goodsId ";
            } else if (query.getStatisticsType().equals(3)) {
                hql += " Group By p2.shopClerkId ";
            } else if (query.getStatisticsType().equals(4)) {//颜色
                hql += " Group By p4.colorSpecificationValueId ";
            } else if (query.getStatisticsType().equals(5)) {//尺码
                hql += " Group By p4.sizeSpecificationValueId ";
            }

            if (query.getByOrderType().equals(1)) {
                orderSql += " ORDER BY p2.clientCreateTime ";
            } else if (query.getByOrderType().equals(2)) {
                orderSql += " ORDER BY totalQuantityCount ";
            } else if (query.getByOrderType().equals(3)) {
                orderSql += " ORDER BY realTotalPriceCount ";
            }

            if (query.getByOrderSortType().equals(2)) {
                orderSql += " DESC";
            }

        } else {
            orderSql = " ORDER BY p2.clientCreateTime DESC";
        }


        //String orderSql=" ORDER BY  totalQuantityCount DESC";
        List<Object[]> lsObj = purchaseOrderProductDao.findSql(sql + hql + orderSql, param, pageNo, row);
	
/*	   
	    private Double realTotalPrice; //实际(实际总价) 
	    private Integer outRealTotalQuantity;//提交上来的（参考）
	    private Double outRealTotalPrice; //提交上来的（参考）
*/
        String sq = "SELECT %s FROM (%s) AS p1";
        try {
            Double realTotalPrice = 0d;
            if (query.getIsStatistics().equals(CommonType.Statistics.YES)) {
                realTotalPrice = Double.valueOf(purchaseOrderProductDao.countSQL3(String.format(sq, "sum(p1.realRetailPrice)", "Select sum(p1.realRetailPrice) AS realRetailPrice " + hql), param).toString());
            } else {
                realTotalPrice = Double.valueOf(purchaseOrderProductDao.countSQL3("Select sum(p1.realRetailPrice) AS realRetailPrice " + hql, param).toString());
            }


            statisticsDto.setRealTotalPrice(realTotalPrice);
        } catch (Exception e1) {
            statisticsDto.setRealTotalPrice(0d);
        }
        try {
            Integer outRealTotalQuantity = 0;
            if (query.getIsStatistics().equals(CommonType.Statistics.YES)) {
                outRealTotalQuantity = Integer.valueOf(purchaseOrderProductDao.countSQL3(String.format(sq, "sum(p1.quantity)", "Select sum(p1.quantity) AS quantity " + hql), param).toString());
            } else {
                outRealTotalQuantity = Integer.valueOf(purchaseOrderProductDao.countSQL3("Select sum(p1.quantity) AS quantity " + hql, param).toString());
            }

            statisticsDto.setOutRealTotalQuantity(outRealTotalQuantity);
        } catch (Exception e) {
            statisticsDto.setOutRealTotalQuantity(0);
        }
        try {
            Double outRealTotalPrice = 0d;
            if (query.getIsStatistics().equals(CommonType.Statistics.YES)) {
                outRealTotalPrice = Double.valueOf(purchaseOrderProductDao.countSQL3(String.format(sq, "sum(p1.realTotalPrice)", "Select sum(p1.realTotalPrice) AS realTotalPrice " + hql), param).toString());
            } else {
                outRealTotalPrice = Double.valueOf(purchaseOrderProductDao.countSQL3("Select sum(p1.realTotalPrice) AS realTotalPrice " + hql, param).toString());
            }
            statisticsDto.setOutRealTotalPrice(outRealTotalPrice);
        } catch (Exception e) {
            statisticsDto.setOutRealTotalPrice(0d);
        }

        Integer count = 0;
        if (query.getIsStatistics().equals(CommonType.Statistics.YES)) {
            count = Integer.valueOf(purchaseOrderProductDao.countSQL3(String.format(sq, "count(p1.id)", "Select count(p1.id) AS id " + hql), param).toString());
        } else {
            count = Integer.valueOf(purchaseOrderProductDao.countSQL3("Select count(p1.id) AS id " + hql, param).toString());
        }

        List<PurchaseSaleOrderProductDto> productList = ResultVoUtil.object2Model(PurchaseSaleOrderProductDto.class, lsObj, sql + hql);
        pager.setList(productList);
        pager.setTotalCount(count);

        return pager;
    }

    @Override
    public Pager findPagerBySaleOrder(Pager pager, PurchaseSaleOrderProductQuery query, PurchaseSaleOrderStatisticsDto statisticsDto) throws OutMsgException, Exception {

        Integer pageNo = pager.getPageNumber();
        Integer row = pager.getPageSize();

        String hql = " FROM PurchaseSaleOrder AS p1 LEFT JOIN MealLocation AS m2 ON p1.mealLocationId=m2.id WHERE p1.isDelete=? ";
        List<Object> param = new ArrayList<Object>();
        param.add(CommonType.Delete.NO);

        if (ObjectUtils.isNotBlank(query.getStartTime())) {
            hql += " AND p1.clientCreateTime>=? ";
            param.add(query.getStartTime());
        }
        if (ObjectUtils.isNotBlank(query.getEndTime())) {
            hql += " AND p1.clientCreateTime<=? ";
            param.add(query.getEndTime());
        }

        if (ObjectUtils.isNotBlank(query.getOutOrderNumber())) {
            hql += " AND p1.outOrderNumber=? ";
            param.add(query.getOutOrderNumber());
        }

        if(PurchaseSaleOrderCategoryType.checkExists(query.getOrderCategory())){
            hql+=" AND p1.orderCategory=? ";
            param.add(query.getOrderCategory());
        }

        if(PurchaseSaleOrderStatusType.checkExists(query.getOrderStatus())){
            hql+=" AND p1.orderStatus=? ";
            param.add(query.getOrderStatus());
        }
        if(PayType.checkExists(query.getPayType())){
            hql+=" AND p1.payType=? ";
            param.add(query.getPayType());
        }

        if (ObjectUtils.isNotBlank(query.getMealLocationId()) && query.getMealLocationId()>0){
            hql+=" AND p1.mealLocationId=? ";
            param.add(query.getMealLocationId());
        }


        String sql= "SELECT p1.orderNumber,p1.outOrderNumber,p1.totalPrice,p1.totalQuantity,p1.realTotalPrice,p1.realRetailPrice,p1.outRealTotalQuantity,p1.outRealTotalPrice,p1.discount,p1.discountPrice"
                + ",p1.orderStatus,p1.orderMark,p1.clientCreateTime,p1.orderCategory,p1.payType,p1.isPay,p1.createTime,p1.modifyTime,p1.payTime,p1.customerName,p1.customerPhone,p1.customerAddress,p1.customerRemark"
                +",p1.mealLocationId,m2.locationName,m2.locationType";


        List<Object[]> lsObj = purchaseOrderProductDao.findSql(sql + hql +" ORDER BY p1.id DESC" , param, pageNo, row);


        try {
            Double realTotalPrice = 0d;
            if (query.getIsStatistics().equals(CommonType.Statistics.YES)) {
                realTotalPrice = Double.valueOf(purchaseOrderProductDao.countSQL3("Select sum(p1.realRetailPrice) AS realRetailPrice " + hql, param).toString());
                //realTotalPrice = Double.valueOf(purchaseOrderProductDao.countSQL3(String.format(sq, "sum(p1.realRetailPrice)", "Select sum(p1.realRetailPrice) AS realRetailPrice " + hql), param).toString());
            } else {
                //realTotalPrice = Double.valueOf(purchaseOrderProductDao.countSQL3("Select sum(p1.realRetailPrice) AS realRetailPrice " + hql, param).toString());
            }
            statisticsDto.setRealTotalPrice(realTotalPrice);
        } catch (Exception e1) {
            statisticsDto.setRealTotalPrice(0d);
        }

        try {
            Integer outRealTotalQuantity = 0;
            if (query.getIsStatistics().equals(CommonType.Statistics.YES)) {
                outRealTotalQuantity = Integer.valueOf(purchaseOrderProductDao.countSQL3("Select sum(p1.totalQuantity) AS quantity " + hql, param).toString());
                //outRealTotalQuantity = Integer.valueOf(purchaseOrderProductDao.countSQL3(String.format(sq, "sum(p1.quantity)", "Select sum(p1.quantity) AS quantity " + hql), param).toString());
            } else {
                //outRealTotalQuantity = Integer.valueOf(purchaseOrderProductDao.countSQL3("Select sum(p1.quantity) AS quantity " + hql, param).toString());
            }

            statisticsDto.setOutRealTotalQuantity(outRealTotalQuantity);
        } catch (Exception e) {
            statisticsDto.setOutRealTotalQuantity(0);
        }
        try {
            Double outRealTotalPrice = 0d;
            if (query.getIsStatistics().equals(CommonType.Statistics.YES)) {
                outRealTotalPrice = Double.valueOf(purchaseOrderProductDao.countSQL3("Select sum(p1.realTotalPrice) AS realTotalPrice " + hql, param).toString());
                //outRealTotalPrice = Double.valueOf(purchaseOrderProductDao.countSQL3(String.format(sq, "sum(p1.realTotalPrice)", "Select sum(p1.realTotalPrice) AS realTotalPrice " + hql), param).toString());
            } else {
               // outRealTotalPrice = Double.valueOf(purchaseOrderProductDao.countSQL3("Select sum(p1.realTotalPrice) AS realTotalPrice " + hql, param).toString());
            }
            statisticsDto.setOutRealTotalPrice(outRealTotalPrice);
        } catch (Exception e) {
            statisticsDto.setOutRealTotalPrice(0d);
        }

        Integer count = 0;
        if (query.getIsStatistics().equals(CommonType.Statistics.YES)) {
            count = Integer.valueOf(purchaseOrderProductDao.countSQL3("Select count(p1.id) AS id " + hql, param).toString());
            // count = Integer.valueOf(purchaseOrderProductDao.countSQL3(String.format(sq, "count(p1.id)", "Select count(p1.id) AS id " + hql), param).toString());
        } else {
           //  count = Integer.valueOf(purchaseOrderProductDao.countSQL3("Select count(p1.id) AS id " + hql, param).toString());
        }

        List<PurchaseSaleOrderDto> orderList = ResultVoUtil.object2Model(PurchaseSaleOrderDto.class, lsObj, sql + hql);
        pager.setList(orderList);
        pager.setTotalCount(count);

        return pager;
    }

    @Override
    public List<PurchaseSaleOrder> findPurchaseSaleOrderList(Integer pageNo, Integer row) {
        String hql = "FROM PurchaseSaleOrder WHERE isDelete=? ";
        List<Object> param = new ArrayList<Object>();
        param.add(CommonType.Delete.NO);
        List<PurchaseSaleOrder> list = purchaseOrderDao.find(hql, param, pageNo, row);

        return list;
    }


    @Override
    public List<PurchaseSaleOrderProduct> findPurchaseSaleOrderProduct(Long purchaseSaleOrderId, Integer pageNo, Integer row) {
        String hql = "FROM PurchaseSaleOrderProduct WHERE purchaseOrderId=?";
        List<Object> param = new ArrayList<Object>();
        param.add(purchaseSaleOrderId);
        List<PurchaseSaleOrderProduct> list = purchaseOrderProductDao.find(hql, param, pageNo, row);

        return list;
    }



    @Resource(name = "MyBaseDao")
    private MyBaseDao<MealLocation> mealLocationDao;
    @Resource(name = "goodsCategoryService")
    private GoodsCategoryService goodsCategoryService;


    @Override
    public SaleOrderCarVo updatePurchaseSaleProduct(PurchaseSaleOrderVo purchaseSaleOrderVo, SaleProductCarVo productCarVo) throws OutMsgException, Exception {

        String outOrderNumber = purchaseSaleOrderVo.getOutOrderNumber();
        Long shopClerkId = purchaseSaleOrderVo.getShopClerkId();
        Long mealLocationId = purchaseSaleOrderVo.getMealLocationId();

        String customerName = purchaseSaleOrderVo.getCustomerName();
        String customerPhone = purchaseSaleOrderVo.getCustomerPhone();
        String customerAddress = purchaseSaleOrderVo.getCustomerAddress();
        String customerRemark = purchaseSaleOrderVo.getCustomerRemark();

        PurchaseSaleOrder purchaseOrder = findByOrderNumber(outOrderNumber);
        if( null == purchaseOrder ){
            Date date = new Date();
            String orderNumber = findOrderNumber();//getOrderNumber(orderType.getPrefix(), date);
            outOrderNumber = orderNumber;

            purchaseOrder = new PurchaseSaleOrder();
            purchaseOrder.setModifyTime(DateUtil.currentDateTime());
            purchaseOrder.setOrderNumber(orderNumber);

            purchaseOrder.setCreateTime(DateUtil.currentDateTime(date));
            purchaseOrder.setIsDelete(CommonType.Delete.NO);
            purchaseOrder.setPurchaseSaleOrderType(PurchaseSaleOrderType.SALE.getType());

            if (null != findByOutOrderNumber(outOrderNumber)) {
                throw new OutMsgException("重复单号");
            }
            purchaseOrder.setIp("");
            //外部提交的数据
            purchaseOrder.setOutOrderNumber(outOrderNumber);
            purchaseOrder.setClientCreateTime(DateUtil.currentDateTime());
            purchaseOrder.setMoneyFloatDigit(0);

            purchaseOrder.setOutRealTotalQuantity(0);
            purchaseOrder.setOutRealTotalPrice(0d);
            purchaseOrder.setDiscountPrice(0d);
            purchaseOrder.setTotalPrice(0d);
            purchaseOrder.setRealRetailPrice(0d);
            purchaseOrder.setRealTotalPrice(0d);
            purchaseOrder.setTotalQuantity(0);
            purchaseOrder.setDiscount(1F);
            purchaseOrder.setDiscountPrice(0d);
            purchaseOrder.setOrderMark("");
            purchaseOrder.setIsPay(CommonType.Pay.NO);
            purchaseOrder.setShopClerkId(shopClerkId);
            purchaseOrder.setPayType(PayType.unknow.getType());

            purchaseOrder.setCustomerName("");
            purchaseOrder.setCustomerPhone("");
            purchaseOrder.setCustomerRemark("");


            purchaseOrder.setOrderStatus(PurchaseSaleOrderStatusType.Reserve.getType());

            MealLocation mealLocation = null;

            purchaseOrder.setMealLocationId(null);
            purchaseOrderDao.save(purchaseOrder);

            if(null != mealLocationId && mealLocationId>0L){
                if (null == mealLocationId || mealLocationId <= 0L) {
                    throw new OutMsgException("参数错误");
                }
                mealLocation = mealLocationDao.get("FROM MealLocation WHERE id=? AND isDelete=?",	new Object[] { mealLocationId, CommonType.Delete.NO });
                if(null == mealLocation){
                    throw new OutMsgException("参数错误");
                }

                if(!mealLocation.getLocationType().equals(MealLocationType.OUT.getType())){
                    mealLocation.setPurchaseSaleOrderId(purchaseOrder.getId());
                    mealLocation.setLocationStatus(MealLocationStatusType.Reserve.getType());
                    mealLocationDao.update(mealLocation);
                }

                purchaseOrder.setMealLocationId(mealLocationId);
                purchaseOrderDao.update(purchaseOrder);
            }
        }

        if(purchaseOrder.getOrderStatus().equals(PurchaseSaleOrderStatusType.Reserve.getType())){
            purchaseOrder.setOrderStatus(PurchaseSaleOrderStatusType.NOTSettlement.getType());

        }

        if(purchaseOrder.getOrderCategory() ==null){
            MealLocation mealLocation = mealLocationDao.get("FROM MealLocation WHERE id=? AND isDelete=?",	new Object[] { mealLocationId, CommonType.Delete.NO });
            if(null == mealLocation){
                throw new OutMsgException("参数错误");
            }
            if(!mealLocation.getLocationType().equals(MealLocationType.OUT.getType())){
                mealLocation.setLocationStatus(MealLocationStatusType.USED.getType());
                mealLocationDao.update(mealLocation);
                purchaseOrder.setOrderCategory(PurchaseSaleOrderCategoryType.SHOPMEAL.getType());
            }else {
                purchaseOrder.setOrderCategory(PurchaseSaleOrderCategoryType.OUTMEAL.getType());
            }
        }




        if(null != customerName  ||  null != customerPhone ||  null != customerRemark ||  null != customerAddress ){
            purchaseOrder.setCustomerName(customerName);
            purchaseOrder.setCustomerPhone(customerPhone);
            purchaseOrder.setCustomerAddress(customerAddress);
            purchaseOrder.setCustomerRemark(customerRemark);
            purchaseOrderDao.update(purchaseOrder);
            return findSinglePurchaseSaleOrder(purchaseOrder.getOutOrderNumber(),true );
        }





        Product product = productService.findByProductId(productCarVo.getProductId());
        if (null == product) {
            throw new OutMsgException("该规格货品不存在");
        }

        Long goodsId = product.getGoodsId();
        Goods goods = goodsService.findByGoodsId(goodsId);
        if (null == goods) {
            throw new OutMsgException("该货品不存在");
        }

        String  unit = goods.getUnit();
        String goodsName = goods.getGoodsName();

        GoodsCategory goodsCategory = goodsCategoryService.findGoodsCategoryById(goods.getGoodsCategoryId());

        if(null == goodsName || (goodsName=goodsName.trim()).length()<=0  ){
            throw new OutMsgException("菜品名不能为空");
        }
        if(null == unit || (unit=unit.trim()).length() <=0  ){
            throw new OutMsgException("菜品单位不能为空");
        }

        String hql ="FROM PurchaseSaleOrderProduct WHERE productId=? AND goodsId=? AND purchaseOrderId=?";
        List<Object> param = new ArrayList<Object>();
        param.add(product.getId());
        param.add(goods.getId());
        param.add(purchaseOrder.getId());

        //
        if(goodsCategory.getIsHide().equals(CommonType.Hide.YES)){
            unit = productCarVo.getUnit();
            goodsName = productCarVo.getGoodsName();
            hql+=" And goodsName=? AND unit=? ";
            param.add(goodsName);
            param.add(unit);
        }

        //查找当前订单是否存在该商品
        PurchaseSaleOrderProduct purchaseOrderProduct =  purchaseOrderProductDao.get(hql, param);
        if (null == purchaseOrderProduct) {
            purchaseOrderProduct = new PurchaseSaleOrderProduct();
            purchaseOrderProduct.setIsDelete(CommonType.Delete.NO);
            purchaseOrderProduct.setPurchaseOrderId(purchaseOrder.getId());
            purchaseOrderProduct.setGoodsId(goodsId);
            purchaseOrderProduct.setProductId(product.getId());
            purchaseOrderProduct.setQuantity(0);
            purchaseOrderProduct.setGoodsName(goodsName);
            purchaseOrderProduct.setUnit(unit);
            purchaseOrderProduct.setDiscount(purchaseOrder.getDiscount());
            purchaseOrderProduct.setDiscountPrice(0d);

        }


        Double retailPrice = goods.getRetailPrice();
        Double tagPrice = goods.getTagPrice();

        Integer quantity = productCarVo.getQuantity();

        Integer productSaleStatus = productCarVo.getProductSaleStatus();

        PurchaseSaleOrderProductStatusType purchaseSaleOrderProductStatusType = PurchaseSaleOrderProductStatusType.find(productSaleStatus);

        if (null == purchaseSaleOrderProductStatusType) {
            throw new OutMsgException("参数错误");
        }
        purchaseOrderProduct.setRetailPrice(retailPrice);
        purchaseOrderProduct.setTagPrice(tagPrice);



        if(productCarVo.getQuantityOpType().equals(1)){
            purchaseOrderProduct.setQuantity(purchaseOrderProduct.getQuantity()+quantity);
        }else if(productCarVo.getQuantityOpType().equals(2)){
            if (purchaseOrderProduct.getQuantity() <=0){
                throw new OutMsgException("不可操作");
            }
            purchaseOrderProduct.setQuantity(purchaseOrderProduct.getQuantity()-quantity);
        }else if(productCarVo.getQuantityOpType().equals(3)){
            if (quantity <0){
                throw new OutMsgException("不可操作");
            }
            purchaseOrderProduct.setQuantity(quantity);
        }

        Double realRetailPrice = 0d;//结算价
        Double realTotalPrice = 0d; //实际总价
        //计算出来的总价

        Double totalPrice = 0d;
        if (purchaseSaleOrderProductStatusType.isOperating()) {
            totalPrice = MoneyUtil.mul(retailPrice, purchaseOrderProduct.getQuantity());
            realRetailPrice = totalPrice;
            if(goodsCategory.getIsCanDiscount().equals(CommonType.Discount.YES)){
                purchaseOrderProduct.setDiscount(purchaseOrder.getDiscount());
                realRetailPrice = MoneyUtil.mul(totalPrice ,purchaseOrderProduct.getDiscount() );
            }else {
                purchaseOrderProduct.setDiscount(1F);
            }
            realTotalPrice =totalPrice;
        }
        purchaseOrderProduct.setRealRetailPrice(realRetailPrice);
        purchaseOrderProduct.setRealTotalPrice(realTotalPrice);
        purchaseOrderProduct.setTotalPrice(totalPrice);
        purchaseOrderProductDao.saveOrUpdate(purchaseOrderProduct);



        purchaseOrder= updateCalc(purchaseOrder);


        purchaseOrderDao.update(purchaseOrder);

        return findSinglePurchaseSaleOrder(purchaseOrder.getOutOrderNumber(),true );
    }

    public PurchaseSaleOrder updateCalc(PurchaseSaleOrder purchaseOrder)throws OutMsgException,Exception{
        Double orderRealRetailPrice = 0d; //付款价
        Integer orderTotalQuantity = 0;
        Double orderRealTotalPrice = 0d; //实际(实际总价) 结算价


        Double orderRealRetailPrice_Discount = 0d; //付款价
        Double orderRealRetailPrice_noDiscount = 0d; //付款价

        List<PurchaseSaleOrderProduct> purchaseSaleOrderProducts = purchaseOrderProductDao.find("FROM PurchaseSaleOrderProduct WHERE  purchaseOrderId=? AND  quantity>0", new Object[]{purchaseOrder.getId()});
        if(null != purchaseSaleOrderProducts && purchaseSaleOrderProducts.size()>0){


            for (int i =0 ;purchaseSaleOrderProducts.size()>i;i++){
                PurchaseSaleOrderProduct purchaseSaleOrderProduct = purchaseSaleOrderProducts.get(i);

                //new
                Double realRetailPrice = 0d;//结算价
                Double realTotalPrice = 0d; //实际总价
                //计算出来的总价
                Double totalPrice = 0d;
                Goods goods = goodsService.findByGoodsId(purchaseSaleOrderProduct.getGoodsId());
                if (null == goods) {
                    throw new OutMsgException("该货品不存在");
                }
                GoodsCategory goodsCategory = goodsCategoryService.findGoodsCategoryById(goods.getGoodsCategoryId());
                if (null == goodsCategory) {
                    throw new OutMsgException("该货品分类不存在");
                }

                totalPrice = MoneyUtil.mul(purchaseSaleOrderProduct.getRetailPrice(), purchaseSaleOrderProduct.getQuantity());
                realRetailPrice = totalPrice;
                if(goodsCategory.getIsCanDiscount().equals(CommonType.Discount.YES)){
                    purchaseSaleOrderProduct.setDiscount(purchaseOrder.getDiscount());
                }else {
                    purchaseSaleOrderProduct.setDiscount(1F);
                }
                realTotalPrice = totalPrice;
                purchaseSaleOrderProduct.setRealRetailPrice(realRetailPrice);
                purchaseSaleOrderProduct.setRealTotalPrice(realTotalPrice);
                purchaseSaleOrderProduct.setTotalPrice(totalPrice);
                //new 2


                orderTotalQuantity        += purchaseSaleOrderProduct.getQuantity();
                orderRealRetailPrice      =  MoneyUtil.add(orderRealRetailPrice,purchaseSaleOrderProduct.getRealRetailPrice()) ;
                orderRealTotalPrice       =  MoneyUtil.add(orderRealTotalPrice,purchaseSaleOrderProduct.getRealTotalPrice())  ;

                if(purchaseSaleOrderProduct.getDiscount().equals(1F)){
                    orderRealRetailPrice_noDiscount = MoneyUtil.add(purchaseSaleOrderProduct.getRealTotalPrice(),orderRealRetailPrice_noDiscount);
                }else {
                    orderRealRetailPrice_Discount = MoneyUtil.add(purchaseSaleOrderProduct.getRealTotalPrice(),orderRealRetailPrice_Discount);
                }
            }
        }

        //整单价格  最后计算 --过滤 不能打折的，
        orderRealRetailPrice = MoneyUtil.mul(orderRealRetailPrice_Discount,purchaseOrder.getDiscount()); //打折的
        orderRealRetailPrice = MoneyUtil.add(orderRealRetailPrice,orderRealRetailPrice_noDiscount); //+ 不打折的


        //外部数据
        purchaseOrder.setOutRealTotalPrice(orderRealRetailPrice);
        purchaseOrder.setOutRealTotalQuantity(orderTotalQuantity);

        purchaseOrder.setTotalPrice(orderRealTotalPrice);
        purchaseOrder.setTotalQuantity(orderTotalQuantity);

        purchaseOrder.setRealTotalPrice(orderRealTotalPrice);



        if(!purchaseOrder.getDiscount().equals(1F)){//打折
            purchaseOrder.setRealRetailPrice(orderRealRetailPrice  );
            purchaseOrder.setDiscountPrice( MoneyUtil.sub(orderRealTotalPrice,   orderRealRetailPrice )  );
        }else {
            purchaseOrder.setRealRetailPrice(MoneyUtil.sub(orderRealRetailPrice , purchaseOrder.getDiscountPrice() )  );
        }
        return purchaseOrder;

    }

    private PurchaseSaleOrder findByOrderNumber(String outOrderNumber){
        PurchaseSaleOrder purchaseOrder = purchaseOrderDao.get(" FROM PurchaseSaleOrder WHERE outOrderNumber=? ", new Object[]{outOrderNumber});
        return purchaseOrder;
    }

    @Override
    public SaleOrderCarVo findSinglePurchaseSaleOrder(String outOrderNumber, boolean checkOrderStatus) throws OutMsgException, Exception {
        PurchaseSaleOrder purchaseSaleOrder = findByOrderNumber(outOrderNumber);
        if (null == purchaseSaleOrder){
            return null;
        }
        if(checkOrderStatus){
            if(purchaseSaleOrder.getOrderStatus().equals( PurchaseSaleOrderStatusType.CANCEL.getType() )
                    || purchaseSaleOrder.getOrderStatus().equals( PurchaseSaleOrderStatusType.Settlement.getType() )     ){
                return null;
            }

        }



        SaleOrderCarVo saleOrderVo = new SaleOrderCarVo();
        BeanUtils.copyProperties(saleOrderVo,purchaseSaleOrder);

        /*
            private Long goodsId; //可无（需检验）
            private Long productId;
            private Double retailPrice;  //销售价格 可无（需检验）
            private Integer quantity;//数量
            private Integer quantityOpType;//quantityOpType ==   1 加  2.减  3.修改

            private Integer productSaleStatus;//销售状态

            //销售部分使用
            private Float discount; //折扣
            private Double discountPrice; //折扣价
            private Double realRetailPrice;//结算价(结算)
            private Double realTotalPrice; //实际总价(生意额)

            private String goodsName;
            private String unit;
            private Integer isHide;
            private Integer isDiscount;
         */

        String hql = "SELECT p1.id AS purchaseSaleOrderProductId,p1.goodsId,p1.productId,g2.retailPrice,p1.quantity,p1.productSaleStatus,p1.discount,p1.discountPrice,p1.realRetailPrice,p1.realTotalPrice,p1.goodsName,p1.unit,g3.isHide,g3.isCanDiscount,g2.goodsCategoryId " +
                " FROM PurchaseSaleOrderProduct AS p1 LEFT JOIN Goods AS g2 ON p1.goodsId = g2.id " +
                " LEFT JOIN GoodsCategory AS g3 ON g2.goodsCategoryId=g3.id "+
                " WHERE p1.purchaseOrderId=? AND p1.quantity>0   ";
        List<Object[]> lsObj = purchaseOrderProductDao.findSql(hql,new Object[]{purchaseSaleOrder.getId() },1,1000);
        if (null == lsObj || lsObj.size()<=0){
            return saleOrderVo;
        }
        List<SaleProductCarVo> saleProductCarVos = ResultVoUtil.object2Model(SaleProductCarVo.class, lsObj, hql);
        saleOrderVo.setSaleProductCars(saleProductCarVos);

        return saleOrderVo;
    }



    @Override
    public boolean updateMoveMealLoaction(String outOrderNumber, Long mealLocationId) throws OutMsgException, Exception {
        PurchaseSaleOrder purchaseSaleOrder = findByOrderNumber(outOrderNumber);
        if (null == purchaseSaleOrder){
            return false;
        }

        if(null==purchaseSaleOrder.getMealLocationId()){
            throw new OutMsgException("错误");
        }

        //本身的桌子腾空。start
        MealLocation mealLocation = mealLocationDao.get("FROM MealLocation WHERE id=? AND isDelete=? ", new Object[]{purchaseSaleOrder.getMealLocationId(),CommonType.Delete.NO});
        if(null == mealLocation){
            throw new OutMsgException("错误");
        }
        if(!mealLocation.getLocationType().equals(MealLocationType.OUT.getType())){
            mealLocation.setPurchaseSaleOrderId(null);
            mealLocation.setLocationStatus(MealLocationStatusType.FREE.getType());
            mealLocationDao.update(mealLocation);
        }

        //本身的桌子腾空。end

        //现在的桌子
        MealLocation mealLocation2 = mealLocationDao.get("FROM MealLocation WHERE id=? AND isDelete=? ", new Object[]{mealLocationId,CommonType.Delete.NO});
        if (null == mealLocation2){
            throw new OutMsgException("错误");
        }
        if(!mealLocation2.getLocationType().equals(MealLocationType.OUT.getType())){
            mealLocation2.setLocationStatus(MealLocationStatusType.USED.getType());
            mealLocation2.setPurchaseSaleOrderId(purchaseSaleOrder.getId());
            mealLocationDao.update(mealLocation2);

            purchaseSaleOrder.setOrderCategory(PurchaseSaleOrderCategoryType.SHOPMEAL.getType());
        }else {
            purchaseSaleOrder.setOrderCategory(PurchaseSaleOrderCategoryType.OUTMEAL.getType());
        }


        purchaseSaleOrder.setMealLocationId(mealLocation2.getId());
        purchaseOrderDao.update(purchaseSaleOrder);

        return true;
    }

    @Override
    public boolean updatePayOrder(String outOrderNumber, Integer payType) throws OutMsgException, Exception {
        PurchaseSaleOrder purchaseSaleOrder = findByOrderNumber(outOrderNumber);
        if (null == purchaseSaleOrder){
            return false;
        }

        if(!PayType.checkExists(payType)){
            throw new OutMsgException("参数错误");
        }
        if(!purchaseSaleOrder.getOrderStatus().equals(PurchaseSaleOrderStatusType.NOTSettlement.getType())){
            throw new OutMsgException("状态错误");
        }



        //本身的桌子腾空。start
        MealLocation mealLocation = mealLocationDao.get("FROM MealLocation WHERE id=? AND isDelete=? ", new Object[]{purchaseSaleOrder.getMealLocationId(),CommonType.Delete.NO});
        if(null == mealLocation){
            throw new OutMsgException("错误");
        }
        if(!mealLocation.getLocationType().equals(MealLocationType.OUT.getType())){
            mealLocation.setPurchaseSaleOrderId(null);
            mealLocation.setLocationStatus(MealLocationStatusType.FREE.getType());
            mealLocationDao.update(mealLocation);
        }

        //本身的桌子腾空。end
        purchaseSaleOrder.setIsPay(CommonType.Pay.YES);
        purchaseSaleOrder.setPayType(payType);
        purchaseSaleOrder.setPayTime(DateUtil.currentDateTime());
        purchaseSaleOrder.setOrderStatus(PurchaseSaleOrderStatusType.Settlement.getType());
        purchaseOrderDao.update(purchaseSaleOrder);

        return true;
    }


    @Override
    public boolean updateCancelOrder(String outOrderNumber) throws OutMsgException, Exception {
        PurchaseSaleOrder purchaseSaleOrder = findByOrderNumber(outOrderNumber);
        if (null == purchaseSaleOrder){
            throw new OutMsgException("参数错误");
        }

        if(null==purchaseSaleOrder.getMealLocationId()){
            throw new OutMsgException("错误");
        }

        //本身的桌子腾空。start
        MealLocation mealLocation = mealLocationDao.get("FROM MealLocation WHERE id=? AND isDelete=? ", new Object[]{purchaseSaleOrder.getMealLocationId(),CommonType.Delete.NO});
        if(null == mealLocation){
            throw new OutMsgException("错误");
        }
        mealLocation.setPurchaseSaleOrderId(null);
        mealLocation.setLocationStatus(MealLocationStatusType.FREE.getType());
        mealLocationDao.update(mealLocation);
        //本身的桌子腾空。end

        purchaseSaleOrder.setOrderStatus(PurchaseSaleOrderStatusType.CANCEL.getType());
        purchaseOrderDao.update(purchaseSaleOrder);

        return true;
    }

    @Override
    public SaleOrderCarVo updateDiscount(String outOrderNumber, Integer discountType, Float discount, Double discountPrice) throws OutMsgException, Exception {
        PurchaseSaleOrder purchaseOrder = findByOrderNumber(outOrderNumber);
        if (null == purchaseOrder){
            throw new OutMsgException("参数错误");
        }


        if(null == discountType){
            throw new OutMsgException("参数错误");
        }
        //1.discountPrice   2. discount  //2 是打折
        if(discountType.equals(1) ){
            discount = 1F;
        }else if (discountType.equals(2)  ){
            discountPrice = 0d;
            if (discount>1 || discount<=0.5){
                throw new OutMsgException("参数错误");
            }
            discount = Float.valueOf(String.valueOf(DoubleArith.round(discount, 2)));
        }else {
            throw new OutMsgException("参数错误");
        }

        purchaseOrder.setDiscount(discount);
        purchaseOrder.setDiscountPrice(discountPrice);

        purchaseOrder = updateCalc(purchaseOrder);

        purchaseOrderDao.update(purchaseOrder);

        return findSinglePurchaseSaleOrder(outOrderNumber,true );
    }

    public void v1(PurchaseSaleOrder purchaseOrder,Integer discountType ,Float discount) throws OutMsgException,Exception{

        Double orderRealRetailPrice = 0d;
        Integer orderTotalQuantity = 0;
        Double orderRealTotalPrice = 0d; //实际(实际总价) 结算价

        List<PurchaseSaleOrderProduct> purchaseSaleOrderProducts = purchaseOrderProductDao.find("FROM PurchaseSaleOrderProduct WHERE  purchaseOrderId=? AND  quantity>0", new Object[]{purchaseOrder.getId()});
        if(null != purchaseSaleOrderProducts && purchaseSaleOrderProducts.size()>0){
            for (int i =0 ;purchaseSaleOrderProducts.size()>i;i++){
                PurchaseSaleOrderProduct purchaseSaleOrderProduct = purchaseSaleOrderProducts.get(i);

                purchaseSaleOrderProduct.setDiscount(1F);
                purchaseSaleOrderProduct.setDiscountPrice(0d);

                purchaseSaleOrderProduct.setRealRetailPrice(MoneyUtil.mul(purchaseSaleOrderProduct.getQuantity(),purchaseSaleOrderProduct.getRetailPrice()));
                purchaseSaleOrderProduct.setRealTotalPrice(MoneyUtil.mul(purchaseSaleOrderProduct.getQuantity(),purchaseSaleOrderProduct.getRetailPrice()));

                if(discountType==2){ //2 是打折
                    Goods goods = goodsService.findByGoodsId(purchaseSaleOrderProduct.getGoodsId());
                    GoodsCategory goodsCategory  = goodsCategoryService.findGoodsCategoryById(goods.getGoodsCategoryId());
                    if(goodsCategory.getIsCanDiscount().equals(CommonType.Discount.YES)){
                        purchaseSaleOrderProduct.setDiscount(discount);
                        purchaseSaleOrderProduct.setRealRetailPrice(MoneyUtil.mul(purchaseSaleOrderProduct.getRealTotalPrice(),discount));
                    }
                }

                purchaseOrderProductDao.update(purchaseSaleOrderProduct);

                orderTotalQuantity        +=   purchaseSaleOrderProduct.getQuantity();
                orderRealRetailPrice      =  MoneyUtil.add(orderRealRetailPrice,purchaseSaleOrderProduct.getRealRetailPrice()) ;
                orderRealTotalPrice       =  MoneyUtil.add(orderRealTotalPrice,purchaseSaleOrderProduct.getRealTotalPrice())  ;

            }
        }

        // * discount -  discountPrice


        //外部数据


        //外部数据
        purchaseOrder.setOutRealTotalPrice(orderRealRetailPrice);
        purchaseOrder.setOutRealTotalQuantity(orderTotalQuantity);

        purchaseOrder.setTotalPrice(orderRealTotalPrice);
        purchaseOrder.setTotalQuantity(orderTotalQuantity);

        purchaseOrder.setRealTotalPrice(orderRealTotalPrice);


        purchaseOrder.setRealRetailPrice(MoneyUtil.sub(orderRealRetailPrice , purchaseOrder.getDiscountPrice() )  );

        if(!purchaseOrder.getDiscount().equals(1F)){
            purchaseOrder.setDiscountPrice( MoneyUtil.sub(orderRealTotalPrice,   orderRealRetailPrice )  );
        }
    }


    @Override
    public List<PurchaseSaleOrder> findOutSendOrderList(Long mealLocationId ) throws OutMsgException, Exception {
        String hql = "FROM PurchaseSaleOrder WHERE isDelete=? ";
        List<Object> param = new ArrayList<Object>();
        param.add(CommonType.Delete.NO);

        if(ObjectUtils.isNotBlank( mealLocationId)){
            hql+=" AND mealLocationId=? ";
            param.add(mealLocationId);
        }

        hql+=" AND (orderStatus=? or orderStatus=?) ";
        param.add(PurchaseSaleOrderStatusType.NOTSettlement.getType());
        param.add(PurchaseSaleOrderStatusType.Reserve.getType());


        List<PurchaseSaleOrder> purchaseSaleOrders = purchaseOrderDao.find(hql, param, 1, 1000);

        return purchaseSaleOrders;
    }


    @Override
    public PurchaseSaleOrderCountVo findCount() throws OutMsgException, Exception {
        PurchaseSaleOrderCountVo vo = new PurchaseSaleOrderCountVo();
        String toDay = DateUtil.currentDate();
        String startTime =  toDay+" 00:00:00";
        String endTime =    toDay+" 23:59:59";

       Long shopMealCount = purchaseOrderDao.count("Select count(id) FROM PurchaseSaleOrder WHERE orderCategory=? AND orderStatus>=? AND createTime>=? AND createTime<=? ",
               new Object[]{PurchaseSaleOrderCategoryType.SHOPMEAL.getType(),PurchaseSaleOrderStatusType.Reserve.getType() ,startTime ,endTime});
        Long outMealCount = purchaseOrderDao.count("Select count(id) FROM PurchaseSaleOrder WHERE orderCategory=? AND orderStatus>=? AND createTime>=? AND createTime<=?  ",
                new Object[]{PurchaseSaleOrderCategoryType.OUTMEAL.getType(),PurchaseSaleOrderStatusType.Reserve.getType() ,startTime ,endTime});
        Long totalCount = purchaseOrderDao.count("Select count(id) FROM PurchaseSaleOrder WHERE  orderStatus>=? AND createTime>=? AND createTime<=? ",
                new Object[]{PurchaseSaleOrderStatusType.Reserve.getType() ,startTime ,endTime});

        vo.setShopMealCount(shopMealCount.intValue());
        vo.setOutMealCount(outMealCount.intValue());
        vo.setTotalCount(totalCount.intValue());

        return vo;
    }

    @Override
    public PurchaseSaleOrderCountVo findOutMealCount(Long mealLocationId) throws OutMsgException, Exception {

        PurchaseSaleOrderCountVo vo = new PurchaseSaleOrderCountVo();

        Long outMealCount = purchaseOrderDao.count("Select count(id) FROM PurchaseSaleOrder WHERE orderStatus>=? AND orderStatus<=? AND mealLocationId=? ",
                new Object[]{ PurchaseSaleOrderStatusType.Reserve.getType(),PurchaseSaleOrderStatusType.NOTSettlement.getType() ,mealLocationId});
        vo.setOutMealCount(outMealCount.intValue());

        return vo;
    }


    @Override
    public List<PurchaseSaleOrderByTypeDto> findStByOrderCategory(PurchaseSaleOrderProductQuery query) {

        List<Object> param = new ArrayList<Object>();
        String hql ="SELECT orderCategory,SUM(realRetailPrice) AS realRetailPrice FROM  PurchasesaleOrder WHERE orderStatus=? ";

        param.add(12);
        if (ObjectUtils.isNotBlank(query.getStartTime())) {
            hql += " AND clientCreateTime>=? ";
            param.add(query.getStartTime());
        }
        if (ObjectUtils.isNotBlank(query.getEndTime())) {
            hql += " AND clientCreateTime<=? ";
            param.add(query.getEndTime());
        }

        hql+=" GROUP BY orderCategory";


        List<Object[]> lsObj = purchaseOrderDao.findSql(hql, param, 1, PurchaseSaleOrderCategoryType.values().length+1);

        return ResultVoUtil.object2Model(PurchaseSaleOrderByTypeDto.class,lsObj,hql);
    }



    @Override
    public List<PurchaseSaleOrderByTypeDto> findStByPayType(PurchaseSaleOrderProductQuery query) {
        List<Object> param  = new ArrayList<Object>();
        String hql="SELECT payType,SUM(realRetailPrice) AS realRetailPrice FROM  PurchasesaleOrder WHERE orderStatus=? ";
        param.add(12);

        if (ObjectUtils.isNotBlank(query.getStartTime())) {
            hql += " AND clientCreateTime>=? ";
            param.add(query.getStartTime());
        }
        if (ObjectUtils.isNotBlank(query.getEndTime())) {
            hql += " AND clientCreateTime<=? ";
            param.add(query.getEndTime());
        }

        hql+=" GROUP BY payType ";
        List<Object[]> lsObj = purchaseOrderDao.findSql(hql, param, 1, PayType.values().length+1);

        return ResultVoUtil.object2Model(PurchaseSaleOrderByTypeDto.class,lsObj,hql);
    }

    @Override
    public PurchaseSaleOrderStatisticsDto findStatistics(PurchaseSaleOrderProductQuery query, PurchaseSaleOrderStatisticsDto statisticsDto){

        List<Object> param  = new ArrayList<Object>();
        String hql="  FROM  PurchasesaleOrder WHERE orderStatus=? ";
        param.add(12);

        if (ObjectUtils.isNotBlank(query.getStartTime())) {
            hql += " AND clientCreateTime>=? ";
            param.add(query.getStartTime());
        }
        if (ObjectUtils.isNotBlank(query.getEndTime())) {
            hql += " AND clientCreateTime<=? ";
            param.add(query.getEndTime());
        }

        try {
            Double realTotalPrice = 0d;
            realTotalPrice = Double.valueOf(purchaseOrderProductDao.countSQL3("Select sum(realRetailPrice) AS realRetailPrice " + hql, param).toString());
            //realTotalPrice = Double.valueOf(purchaseOrderProductDao.countSQL3(String.format(sq, "sum(p1.realRetailPrice)", "Select sum(p1.realRetailPrice) AS realRetailPrice " + hql), param).toString());

            statisticsDto.setRealTotalPrice(realTotalPrice);
        } catch (Exception e1) {
            statisticsDto.setRealTotalPrice(0d);
        }

        try {
            Integer outRealTotalQuantity = 0;
            outRealTotalQuantity = Integer.valueOf(purchaseOrderProductDao.countSQL3("Select sum(totalQuantity) AS quantity " + hql, param).toString());


            statisticsDto.setOutRealTotalQuantity(outRealTotalQuantity);
        } catch (Exception e) {
            statisticsDto.setOutRealTotalQuantity(0);
        }
        try {
            Double outRealTotalPrice = 0d;
            outRealTotalPrice = Double.valueOf(purchaseOrderProductDao.countSQL3("Select sum(realTotalPrice) AS realTotalPrice " + hql, param).toString());
            statisticsDto.setOutRealTotalPrice(outRealTotalPrice);
        } catch (Exception e) {
            statisticsDto.setOutRealTotalPrice(0d);
        }

        return statisticsDto;
    }



}
